<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>字幕设置工具</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f5f5f5;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 10px;
            box-shadow: 0 5px 15px rgba(0,0,0,0.1);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            text-align: center;
        }

        .header h1 {
            font-size: 2em;
            margin-bottom: 10px;
        }

        .header p {
            opacity: 0.9;
        }

        .main-content {
            padding: 20px;
        }

        .video-section {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-bottom: 20px;
        }

        .video-player {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 8px;
        }

        .video-player h3 {
            margin-bottom: 10px;
            color: #333;
        }

        .video-controls {
            margin-bottom: 10px;
        }

        .video-controls button {
            margin-right: 10px;
            padding: 8px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            background: #667eea;
            color: white;
        }

        .video-controls button:hover {
            background: #5a6fd8;
        }

        .video-controls button:disabled {
            background: #ccc;
            cursor: not-allowed;
        }

        #videoElement {
            width: 100%;
            max-width: 100%;
            border-radius: 5px;
        }

        .canvas-section {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 8px;
        }

        .canvas-section h3 {
            margin-bottom: 10px;
            color: #333;
        }

        .canvas-container {
            position: relative;
            border: 2px solid #ddd;
            border-radius: 5px;
            overflow: hidden;
        }

        #drawingCanvas {
            display: block;
            max-width: 100%;
            height: auto;
            cursor: crosshair;
        }

        .canvas-drawing {
            cursor: crosshair;
        }

        .canvas-dragging {
            cursor: grab;
        }

        .canvas-dragging:active {
            cursor: grabbing;
        }

        .controls {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin-bottom: 20px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
        }

        .control-group {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }

        .control-group label {
            font-weight: 600;
            color: #333;
            font-size: 0.9em;
        }

        .control-group input, .control-group select, .control-group textarea {
            padding: 8px;
            border: 2px solid #e1e5e9;
            border-radius: 5px;
            font-size: 14px;
        }

        .control-group input:focus, .control-group select:focus, .control-group textarea:focus {
            outline: none;
            border-color: #667eea;
        }

        .color-picker {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .color-picker input[type="color"] {
            width: 40px;
            height: 35px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }

        .button-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 15px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
        }

        .left-buttons {
            display: flex;
            gap: 10px;
        }

        .right-buttons {
            display: flex;
            gap: 10px;
        }

        .btn {
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .btn-primary {
            background: #667eea;
            color: white;
        }

        .btn-primary:hover {
            background: #5a6fd8;
        }

        .btn-secondary {
            background: #6c757d;
            color: white;
        }

        .btn-secondary:hover {
            background: #5a6268;
        }

        .btn-danger {
            background: #dc3545;
            color: white;
        }

        .btn-danger:hover {
            background: #c82333;
        }

        .btn-success {
            background: #28a745;
            color: white;
        }

        .btn-success:hover {
            background: #218838;
        }

        .info-panel {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 8px;
            margin-top: 20px;
        }

        .info-panel h3 {
            color: #333;
            margin-bottom: 15px;
        }

        .info-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
        }

        .info-item {
            background: white;
            padding: 10px;
            border-radius: 5px;
            border-left: 3px solid #667eea;
        }

        .info-item h4 {
            color: #667eea;
            margin-bottom: 5px;
            font-size: 0.9em;
        }

        .info-item p {
            color: #666;
            font-size: 0.9em;
        }

        .subtitle-data {
            background: #e8f5e8;
            padding: 15px;
            border-radius: 8px;
            margin-top: 20px;
            border-left: 4px solid #28a745;
        }

        .subtitle-data h3 {
            color: #28a745;
            margin-bottom: 10px;
        }

        .subtitle-data pre {
            background: white;
            padding: 10px;
            border-radius: 5px;
            overflow-x: auto;
            font-size: 0.9em;
        }

        .subtitle-item {
            position: absolute;
            border: 2px solid #ff4757;
            background: rgba(255, 71, 87, 0.1);
            cursor: move;
            padding: 5px;
            border-radius: 3px;
        }

        .subtitle-resize-handle {
            position: absolute;
            width: 8px;
            height: 8px;
            background: #ff4757;
            border: 1px solid white;
            cursor: se-resize;
        }

        .resize-handle-n {
            top: -4px;
            left: 50%;
            transform: translateX(-50%);
            cursor: n-resize;
        }

        .resize-handle-s {
            bottom: -4px;
            left: 50%;
            transform: translateX(-50%);
            cursor: s-resize;
        }

        .resize-handle-e {
            right: -4px;
            top: 50%;
            transform: translateY(-50%);
            cursor: e-resize;
        }

        .resize-handle-w {
            left: -4px;
            top: 50%;
            transform: translateY(-50%);
            cursor: w-resize;
        }

        .resize-handle-ne {
            top: -4px;
            right: -4px;
            cursor: ne-resize;
        }

        .resize-handle-nw {
            top: -4px;
            left: -4px;
            cursor: nw-resize;
        }

        .resize-handle-se {
            bottom: -4px;
            right: -4px;
            cursor: se-resize;
        }

        .resize-handle-sw {
            bottom: -4px;
            left: -4px;
            cursor: sw-resize;
        }

        @media (max-width: 768px) {
            .video-section {
                grid-template-columns: 1fr;
            }
            
            .controls {
                grid-template-columns: 1fr;
            }
            
            .button-row {
                flex-direction: column;
                gap: 10px;
            }
            
            .left-buttons, .right-buttons {
                width: 100%;
                justify-content: center;
            }
            
            .btn {
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📝 字幕设置工具</h1>
            <p>上传视频和字幕文件，设置字幕样式和位置，生成带字幕的视频</p>
        </div>

        <div class="main-content">
            <!-- 视频播放和画布区域 -->
            <div class="video-section">
                <div class="video-player">
                    <h3>📹 视频播放</h3>
                    <div class="video-controls">
                        <button id="loadVideo">选择视频</button>
                        <button id="playVideo">播放</button>
                        <button id="pauseVideo">暂停</button>
                        <button id="captureFrame">提取当前帧</button>
                    </div>
                    <video id="videoElement" controls>
                        您的浏览器不支持视频播放
                    </video>
                    <input type="file" id="videoFile" accept="video/*" style="display: none;">
                </div>

                <div class="canvas-section">
                    <h3>🎨 字幕位置设置（拖拽创建字幕显示区域，用于定义字幕在视频中的位置）</h3>
                    <div class="canvas-container">
                        <canvas id="drawingCanvas" width="800" height="450"></canvas>
                    </div>
                </div>
            </div>

            <!-- 控制面板 -->
            <div class="controls">
                <div class="control-group">
                    <label for="subtitleText">字幕文本（可选，用于预览样式）</label>
                    <textarea id="subtitleText" rows="3" placeholder="请输入预览字幕文本...">示例字幕文本</textarea>
                </div>

                <div class="control-group">
                    <label for="subtitleFile">上传字幕文件</label>
                    <input type="file" id="subtitleFile" accept=".srt,.ass,.ssa,.vtt" style="padding: 8px; border: 2px solid #e1e5e9; border-radius: 5px; font-size: 14px;">
                    <small style="color: #666; font-size: 0.8em;">支持SRT、ASS、SSA、VTT格式</small>
                </div>

                <div class="control-group">
                    <label for="subtitleColor">字幕颜色</label>
                    <div class="color-picker">
                        <input type="color" id="subtitleColor" value="#ffffff">
                        <span id="colorValue">#ffffff</span>
                    </div>
                </div>

                <div class="control-group">
                    <label for="subtitleStrokeColor">描边颜色</label>
                    <div class="color-picker">
                        <input type="color" id="subtitleStrokeColor" value="#000000">
                        <span id="strokeColorValue">#000000</span>
                    </div>
                </div>

                <div class="control-group">
                    <label for="subtitleStrokeWidth">描边宽度</label>
                    <input type="range" id="subtitleStrokeWidth" min="0" max="10" value="2">
                    <span id="strokeWidthValue">2px</span>
                </div>

                <div class="control-group">
                    <label for="subtitleSize">字体大小</label>
                    <input type="range" id="subtitleSize" min="12" max="72" value="24">
                    <span id="sizeValue">24px</span>
                </div>

                <div class="control-group">
                    <label for="subtitleAlign">对齐方式</label>
                    <select id="subtitleAlign">
                        <option value="left">左对齐</option>
                        <option value="center" selected>居中对齐</option>
                        <option value="right">右对齐</option>
                    </select>
                </div>

                <div class="control-group">
                    <label for="subtitleOpacity">透明度</label>
                    <input type="range" id="subtitleOpacity" min="0" max="100" value="100">
                    <span id="opacityValue">100%</span>
                </div>
            </div>

            <!-- 操作按钮行 -->
            <div class="button-row">
                <div class="left-buttons">
                    <button class="btn btn-primary" id="startDraw">开始设置</button>
                    <button class="btn btn-secondary" id="clearAll">清除所有</button>
                </div>
                <div class="right-buttons">
                    <button class="btn btn-success" id="getSubtitleData">获取字幕数据</button>
                    <button class="btn btn-primary" id="applySubtitle">应用字幕</button>
                </div>
            </div>

            <!-- 信息面板 -->
            <div class="info-panel">
                <h3>📊 状态信息</h3>
                <div class="info-grid">
                    <div class="info-item">
                        <h4>字幕文件</h4>
                        <p id="subtitleFileStatus">未上传</p>
                    </div>
                    <div class="info-item">
                        <h4>字幕位置区域</h4>
                        <p id="positionCount">0</p>
                    </div>
                    <div class="info-item">
                        <h4>鼠标位置</h4>
                        <p id="mousePosition">(0, 0)</p>
                    </div>
                    <div class="info-item">
                        <h4>画布尺寸</h4>
                        <p id="canvasSize">800 x 450</p>
                    </div>
                    <div class="info-item">
                        <h4>设置状态</h4>
                        <p id="drawStatus">未开始</p>
                    </div>
                </div>
                <div style="margin-top: 15px; padding: 10px; background: #e3f2fd; border-radius: 5px; border-left: 4px solid #2196f3;">
                    <h4 style="color: #2196f3; margin-bottom: 8px;">💡 使用说明</h4>
                    <ul style="color: #666; font-size: 0.9em; margin: 0; padding-left: 20px;">
                        <li><strong>上传视频</strong>：选择要处理的视频文件</li>
                        <li><strong>上传字幕文件</strong>：选择SRT、ASS等格式的字幕文件</li>
                        <li><strong>设置样式</strong>：在控制面板设置字幕的颜色、描边、大小等样式</li>
                        <li><strong>设置位置</strong>：在画布上拖拽创建字幕显示区域</li>
                        <li>点击"开始设置"按钮进入设置模式</li>
                        <li>在画布上点击创建字幕位置，或拖拽绘制字幕区域</li>
                        <li>拖拽字幕边框可以移动字幕位置</li>
                        <li>拖拽红色圆点可以调整字幕大小</li>
                        <li>在控制面板修改字幕样式会实时更新</li>
                        <li>点击"应用字幕"生成带字幕的视频文件</li>
                    </ul>
                </div>
            </div>

            <!-- 字幕数据 -->
            <div class="subtitle-data">
                <h3>📋 字幕数据</h3>
                <pre id="subtitleDataOutput">暂无字幕数据</pre>
            </div>
        </div>
    </div>

    <script>
        class SubtitleTool {
            constructor() {
                this.videoElement = document.getElementById('videoElement');
                this.canvas = document.getElementById('drawingCanvas');
                this.ctx = this.canvas.getContext('2d');
                this.subtitles = [];
                this.subtitleFile = null; // 存储字幕文件引用
                this.isDrawing = false;
                this.drawStart = null;
                this.currentFrame = null;
                this.selectedSubtitle = null;
                this.isDragging = false;
                this.isResizing = false;
                this.dragOffset = { x: 0, y: 0 };
                this.resizeDirection = null;
                this.isMouseDown = false;
                
                this.initializeEventListeners();
                this.drawTestPattern();
            }
            
            initializeEventListeners() {
                // 视频控制
                document.getElementById('loadVideo').addEventListener('click', () => {
                    document.getElementById('videoFile').click();
                });

                document.getElementById('videoFile').addEventListener('change', (e) => {
                    this.loadVideo(e.target.files[0]);
                });

                document.getElementById('playVideo').addEventListener('click', () => {
                    this.videoElement.play();
                });

                document.getElementById('pauseVideo').addEventListener('click', () => {
                    this.videoElement.pause();
                });

                document.getElementById('captureFrame').addEventListener('click', () => {
                    this.captureCurrentFrame();
                });

                // 控制面板
                document.getElementById('subtitleText').addEventListener('input', (e) => {
                    this.updateAllSubtitles();
                });

                document.getElementById('subtitleFile').addEventListener('change', (e) => {
                    this.handleSubtitleFileUpload(e.target.files[0]);
                });

                document.getElementById('subtitleColor').addEventListener('change', (e) => {
                    document.getElementById('colorValue').textContent = e.target.value;
                    this.updateAllSubtitles();
                });

                document.getElementById('subtitleStrokeColor').addEventListener('change', (e) => {
                    document.getElementById('strokeColorValue').textContent = e.target.value;
                    this.updateAllSubtitles();
                });

                document.getElementById('subtitleStrokeWidth').addEventListener('input', (e) => {
                    document.getElementById('strokeWidthValue').textContent = e.target.value + 'px';
                    this.updateAllSubtitles();
                });

                document.getElementById('subtitleSize').addEventListener('input', (e) => {
                    document.getElementById('sizeValue').textContent = e.target.value + 'px';
                    this.updateAllSubtitles();
                });

                document.getElementById('subtitleAlign').addEventListener('change', (e) => {
                    this.updateAllSubtitles();
                });

                document.getElementById('subtitleOpacity').addEventListener('input', (e) => {
                    document.getElementById('opacityValue').textContent = e.target.value + '%';
                    this.updateAllSubtitles();
                });

                document.getElementById('startDraw').addEventListener('click', () => {
                    this.toggleDrawing();
                });

                document.getElementById('clearAll').addEventListener('click', () => {
                    this.clearAllSubtitles();
                });

                document.getElementById('getSubtitleData').addEventListener('click', () => {
                    this.getSubtitleData();
                });

                document.getElementById('applySubtitle').addEventListener('click', () => {
                    this.applySubtitleToVideo();
                });

                // 画布事件
                this.canvas.addEventListener('mousedown', (e) => this.handleMouseDown(e));
                this.canvas.addEventListener('mousemove', (e) => this.handleMouseMove(e));
                this.canvas.addEventListener('mouseup', (e) => this.handleMouseUp(e));
                this.canvas.addEventListener('mouseleave', (e) => this.handleMouseLeave(e));
            }
            
            updateCanvasCursor() {
                if (this.isDrawing) {
                    this.canvas.classList.add('canvas-drawing');
                    this.canvas.classList.remove('canvas-dragging');
                } else {
                    this.canvas.classList.remove('canvas-drawing');
                    this.canvas.classList.add('canvas-dragging');
                }
            }
            
            drawTestPattern() {
                this.ctx.fillStyle = '#f0f0f0';
                this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
                
                this.ctx.fillStyle = '#333';
                this.ctx.font = '20px Arial';
                this.ctx.textAlign = 'center';
                this.ctx.fillText('字幕设置工具', this.canvas.width/2, this.canvas.height/2);
                
                this.ctx.font = '14px Arial';
                this.ctx.fillText('选择视频并提取帧，然后设置字幕样式', this.canvas.width/2, this.canvas.height/2 + 30);
            }
            
            loadVideo(file) {
                if (!file) return;
                
                const url = URL.createObjectURL(file);
                this.videoElement.src = url;
                this.videoElement.load();
                
                // 启用视频控制按钮
                document.getElementById('playVideo').disabled = false;
                document.getElementById('pauseVideo').disabled = false;
                document.getElementById('captureFrame').disabled = false;
            }
            
            captureCurrentFrame() {
                if (this.videoElement.paused) {
                    alert('请先播放视频');
                    return;
                }
                
                // 创建临时canvas来捕获视频帧
                const tempCanvas = document.createElement('canvas');
                const tempCtx = tempCanvas.getContext('2d');
                
                tempCanvas.width = this.videoElement.videoWidth;
                tempCanvas.height = this.videoElement.videoHeight;
                
                // 绘制当前帧
                tempCtx.drawImage(this.videoElement, 0, 0);
                
                // 调整画布尺寸以匹配视频
                this.canvas.width = this.videoElement.videoWidth;
                this.canvas.height = this.videoElement.videoHeight;
                
                // 将帧绘制到主画布
                this.ctx.drawImage(tempCanvas, 0, 0);
                this.currentFrame = tempCanvas;
                
                this.updateCanvasSize();
                this.drawSubtitles();
                
                document.getElementById('drawStatus').textContent = '帧已提取，可以开始设置字幕';
            }
            
            drawSubtitles() {
                if (!this.currentFrame) return;
                
                // 重新绘制当前帧
                this.ctx.drawImage(this.currentFrame, 0, 0);
                
                // 绘制所有字幕
                this.subtitles.forEach(subtitle => {
                    this.drawSubtitle(subtitle);
                });
            }
            
            drawSubtitle(subtitle) {
                this.ctx.save();
                this.ctx.globalAlpha = subtitle.opacity / 100;
                this.ctx.font = `${subtitle.size}px Arial`;
                this.ctx.textAlign = subtitle.align;
                
                // 使用字幕的实际位置（基于鼠标点击位置）
                let x, y;
                
                // 根据对齐方式计算X坐标（相对于字幕区域的中心点）
                switch (subtitle.align) {
                    case 'left':
                        x = subtitle.x + 10; // 距离字幕区域左边缘10px
                        break;
                    case 'center':
                        x = subtitle.x + subtitle.width / 2; // 字幕区域中心
                        break;
                    case 'right':
                        x = subtitle.x + subtitle.width - 10; // 距离字幕区域右边缘10px
                        break;
                }
                
                // Y坐标使用字幕区域中心
                y = subtitle.y + subtitle.height / 2 + subtitle.size / 3;
                
                // 绘制字幕区域边框
                this.ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
                this.ctx.lineWidth = 2;
                this.ctx.strokeRect(subtitle.x, subtitle.y, subtitle.width, subtitle.height);
                
                // 绘制拖拽手柄
                this.drawDragHandles(subtitle);
                
                // 绘制文本位置标记（调试用）
                this.ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
                this.ctx.beginPath();
                this.ctx.arc(x, y, 3, 0, 2 * Math.PI);
                this.ctx.fill();
                
                // 绘制描边文本
                if (subtitle.strokeWidth > 0) {
                    this.ctx.strokeStyle = subtitle.strokeColor;
                    this.ctx.lineWidth = subtitle.strokeWidth;
                    this.ctx.strokeText(subtitle.text, x, y);
                }
                
                // 绘制填充文本
                this.ctx.fillStyle = subtitle.color;
                this.ctx.fillText(subtitle.text, x, y);
                
                this.ctx.restore();
            }
            
            drawDragHandles(subtitle) {
                // 绘制四个角的拖拽手柄
                const handleSize = 6;
                const handles = [
                    { x: subtitle.x, y: subtitle.y }, // 左上
                    { x: subtitle.x + subtitle.width, y: subtitle.y }, // 右上
                    { x: subtitle.x, y: subtitle.y + subtitle.height }, // 左下
                    { x: subtitle.x + subtitle.width, y: subtitle.y + subtitle.height } // 右下
                ];
                
                this.ctx.fillStyle = 'rgba(255, 0, 0, 0.8)';
                this.ctx.strokeStyle = 'white';
                this.ctx.lineWidth = 1;
                
                handles.forEach(handle => {
                    this.ctx.beginPath();
                    this.ctx.arc(handle.x, handle.y, handleSize, 0, 2 * Math.PI);
                    this.ctx.fill();
                    this.ctx.stroke();
                });
            }
            
            updateAllSubtitles() {
                const newText = document.getElementById('subtitleText').value;
                const newColor = document.getElementById('subtitleColor').value;
                const newStrokeColor = document.getElementById('subtitleStrokeColor').value;
                const newStrokeWidth = parseInt(document.getElementById('subtitleStrokeWidth').value);
                const newSize = parseInt(document.getElementById('subtitleSize').value);
                const newAlign = document.getElementById('subtitleAlign').value;
                const newOpacity = parseInt(document.getElementById('subtitleOpacity').value);
                
                // 更新所有字幕的样式
                this.subtitles.forEach(subtitle => {
                    subtitle.text = newText;
                    subtitle.color = newColor;
                    subtitle.strokeColor = newStrokeColor;
                    subtitle.strokeWidth = newStrokeWidth;
                    subtitle.size = newSize;
                    subtitle.align = newAlign;
                    subtitle.opacity = newOpacity;
                });
                
                // 重新绘制
                this.drawSubtitles();
            }
            
            toggleDrawing() {
                this.isDrawing = !this.isDrawing;
                const btn = document.getElementById('startDraw');
                const status = document.getElementById('drawStatus');
                
                if (this.isDrawing) {
                    btn.textContent = '停止设置';
                    btn.classList.remove('btn-primary');
                    btn.classList.add('btn-danger');
                    status.textContent = '设置中';
                } else {
                    btn.textContent = '开始设置';
                    btn.classList.remove('btn-danger');
                    btn.classList.add('btn-primary');
                    status.textContent = '未开始';
                }
                
                this.updateCanvasCursor();
            }
            
            handleMouseDown(e) {
                this.isMouseDown = true;
                const rect = this.canvas.getBoundingClientRect();
                const x = e.clientX - rect.left;
                const y = e.clientY - rect.top;
                
                // 计算画布缩放比例
                const scaleX = this.canvas.width / rect.width;
                const scaleY = this.canvas.height / rect.height;
                
                // 转换为画布坐标
                const canvasX = x * scaleX;
                const canvasY = y * scaleY;
                
                // 检查是否点击了调整手柄
                const resizeHandle = this.getResizeHandleAtPosition(x, y);
                if (resizeHandle) {
                    this.selectedSubtitle = resizeHandle.subtitle;
                    this.isResizing = true;
                    this.resizeDirection = resizeHandle.direction;
                    return;
                }
                
                // 检查是否点击了现有字幕
                const clickedSubtitle = this.getSubtitleAtPosition(x, y);
                if (clickedSubtitle) {
                    this.selectedSubtitle = clickedSubtitle;
                    this.isDragging = true;
                    this.dragOffset = { x: canvasX - clickedSubtitle.x, y: canvasY - clickedSubtitle.y };
                    return;
                }
                
                // 开始绘制新字幕（在任何位置都可以开始）
                if (this.isDrawing) {
                    this.drawStart = { x: canvasX, y: canvasY };
                }
            }
            
            handleMouseMove(e) {
                const rect = this.canvas.getBoundingClientRect();
                const x = e.clientX - rect.left;
                const y = e.clientY - rect.top;
                
                // 计算画布缩放比例
                const scaleX = this.canvas.width / rect.width;
                const scaleY = this.canvas.height / rect.height;
                
                // 转换为画布坐标
                const canvasX = x * scaleX;
                const canvasY = y * scaleY;
                
                document.getElementById('mousePosition').textContent = `(${Math.round(canvasX)}, ${Math.round(canvasY)})`;
                
                if (this.isDragging && this.selectedSubtitle) {
                    // 拖拽字幕区域 - 限制在画布范围内
                    const newX = Math.max(0, Math.min(this.canvas.width - this.selectedSubtitle.width, canvasX - this.dragOffset.x));
                    const newY = Math.max(0, Math.min(this.canvas.height - this.selectedSubtitle.height, canvasY - this.dragOffset.y));
                    
                    this.selectedSubtitle.x = newX;
                    this.selectedSubtitle.y = newY;
                    this.drawSubtitles();
                } else if (this.isResizing && this.selectedSubtitle) {
                    // 调整字幕区域大小
                    this.resizeSubtitle(this.selectedSubtitle, canvasX, canvasY);
                    this.drawSubtitles();
                } else if (this.isDrawing && this.drawStart && this.isMouseDown) {
                    // 绘制预览 - 在任何位置都可以绘制
                    this.drawPreviewSubtitle(this.drawStart, { x: canvasX, y: canvasY });
                }
            }
            
            handleMouseUp(e) {
                this.isMouseDown = false;
                
                if (this.isDrawing && this.drawStart) {
                    const rect = this.canvas.getBoundingClientRect();
                    const x = e.clientX - rect.left;
                    const y = e.clientY - rect.top;
                    
                    // 计算画布缩放比例
                    const scaleX = this.canvas.width / rect.width;
                    const scaleY = this.canvas.height / rect.height;
                    
                    // 转换为画布坐标
                    const canvasX = x * scaleX;
                    const canvasY = y * scaleY;
                    
                    const end = { x: canvasX, y: canvasY };
                    
                    // 如果只是点击（没有拖拽），在点击位置创建默认大小的字幕
                    const distance = Math.sqrt(
                        Math.pow(end.x - this.drawStart.x, 2) + 
                        Math.pow(end.y - this.drawStart.y, 2)
                    );
                    
                    if (distance < 5) {
                        // 点击创建字幕
                        this.createSubtitleAtPosition(this.drawStart);
                    } else {
                        // 拖拽创建字幕
                        this.createSubtitle(this.drawStart, end);
                    }
                    
                    this.drawStart = null;
                }
                
                this.isDragging = false;
                this.isResizing = false;
                this.selectedSubtitle = null;
                this.resizeDirection = null;
            }
            
            handleMouseLeave(e) {
                this.isMouseDown = false;
                this.drawStart = null;
                this.isDragging = false;
                this.isResizing = false;
                this.selectedSubtitle = null;
                this.resizeDirection = null;
            }
            
            getSubtitleAtPosition(x, y) {
                // 计算画布缩放比例
                const rect = this.canvas.getBoundingClientRect();
                const scaleX = this.canvas.width / rect.width;
                const scaleY = this.canvas.height / rect.height;
                
                // 转换为画布坐标
                const canvasX = x * scaleX;
                const canvasY = y * scaleY;
                
                for (let i = this.subtitles.length - 1; i >= 0; i--) {
                    const subtitle = this.subtitles[i];
                    if (canvasX >= subtitle.x && canvasX <= subtitle.x + subtitle.width &&
                        canvasY >= subtitle.y && canvasY <= subtitle.y + subtitle.height) {
                        return subtitle;
                    }
                }
                return null;
            }
            
            getResizeHandleAtPosition(x, y) {
                // 计算画布缩放比例
                const rect = this.canvas.getBoundingClientRect();
                const scaleX = this.canvas.width / rect.width;
                const scaleY = this.canvas.height / rect.height;
                
                // 转换为画布坐标
                const canvasX = x * scaleX;
                const canvasY = y * scaleY;
                
                for (let i = this.subtitles.length - 1; i >= 0; i--) {
                    const subtitle = this.subtitles[i];
                    
                    // 检查8个方向的调整手柄
                    const handles = [
                        { x: subtitle.x + subtitle.width/2, y: subtitle.y - 4, direction: 'n' },
                        { x: subtitle.x + subtitle.width/2, y: subtitle.y + subtitle.height + 4, direction: 's' },
                        { x: subtitle.x + subtitle.width + 4, y: subtitle.y + subtitle.height/2, direction: 'e' },
                        { x: subtitle.x - 4, y: subtitle.y + subtitle.height/2, direction: 'w' },
                        { x: subtitle.x + subtitle.width + 4, y: subtitle.y - 4, direction: 'ne' },
                        { x: subtitle.x - 4, y: subtitle.y - 4, direction: 'nw' },
                        { x: subtitle.x + subtitle.width + 4, y: subtitle.y + subtitle.height + 4, direction: 'se' },
                        { x: subtitle.x - 4, y: subtitle.y + subtitle.height + 4, direction: 'sw' }
                    ];
                    
                    for (const handle of handles) {
                        if (canvasX >= handle.x - 4 && canvasX <= handle.x + 4 &&
                            canvasY >= handle.y - 4 && canvasY <= handle.y + 4) {
                            return { subtitle, direction: handle.direction };
                        }
                    }
                }
                return null;
            }
            
            resizeSubtitle(subtitle, x, y) {
                const minSize = 20;
                
                switch (this.resizeDirection) {
                    case 'n':
                        const newHeight = subtitle.y + subtitle.height - y;
                        if (newHeight >= minSize) {
                            subtitle.height = newHeight;
                            subtitle.y = y;
                        }
                        break;
                    case 's':
                        const newHeight2 = y - subtitle.y;
                        if (newHeight2 >= minSize) {
                            subtitle.height = newHeight2;
                        }
                        break;
                    case 'e':
                        const newWidth = x - subtitle.x;
                        if (newWidth >= minSize) {
                            subtitle.width = newWidth;
                        }
                        break;
                    case 'w':
                        const newWidth2 = subtitle.x + subtitle.width - x;
                        if (newWidth2 >= minSize) {
                            subtitle.width = newWidth2;
                            subtitle.x = x;
                        }
                        break;
                    case 'ne':
                        const newHeight3 = subtitle.y + subtitle.height - y;
                        const newWidth3 = x - subtitle.x;
                        if (newHeight3 >= minSize && newWidth3 >= minSize) {
                            subtitle.height = newHeight3;
                            subtitle.y = y;
                            subtitle.width = newWidth3;
                        }
                        break;
                    case 'nw':
                        const newHeight4 = subtitle.y + subtitle.height - y;
                        const newWidth4 = subtitle.x + subtitle.width - x;
                        if (newHeight4 >= minSize && newWidth4 >= minSize) {
                            subtitle.height = newHeight4;
                            subtitle.y = y;
                            subtitle.width = newWidth4;
                            subtitle.x = x;
                        }
                        break;
                    case 'se':
                        const newHeight5 = y - subtitle.y;
                        const newWidth5 = x - subtitle.x;
                        if (newHeight5 >= minSize && newWidth5 >= minSize) {
                            subtitle.height = newHeight5;
                            subtitle.width = newWidth5;
                        }
                        break;
                    case 'sw':
                        const newHeight6 = y - subtitle.y;
                        const newWidth6 = subtitle.x + subtitle.width - x;
                        if (newHeight6 >= minSize && newWidth6 >= minSize) {
                            subtitle.height = newHeight6;
                            subtitle.width = newWidth6;
                            subtitle.x = x;
                        }
                        break;
                }
            }
            
            drawPreviewSubtitle(start, end) {
                this.drawSubtitles();
                
                const text = document.getElementById('subtitleText').value;
                const color = document.getElementById('subtitleColor').value;
                const strokeColor = document.getElementById('subtitleStrokeColor').value;
                const strokeWidth = parseInt(document.getElementById('subtitleStrokeWidth').value);
                const size = parseInt(document.getElementById('subtitleSize').value);
                const align = document.getElementById('subtitleAlign').value;
                const opacity = parseInt(document.getElementById('subtitleOpacity').value);
                
                this.ctx.save();
                this.ctx.globalAlpha = opacity / 100;
                this.ctx.font = `${size}px Arial`;
                this.ctx.textAlign = align;
                
                // 计算预览区域
                const previewX = Math.min(start.x, end.x);
                const previewY = Math.min(start.y, end.y);
                const previewWidth = Math.abs(end.x - start.x);
                const previewHeight = Math.abs(end.y - start.y);
                
                // 确保最小尺寸
                const minWidth = Math.max(100, previewWidth);
                const minHeight = Math.max(size + 20, previewHeight);
                
                // 计算预览文本位置（基于预览区域）
                let x, y;
                
                // 根据对齐方式计算X坐标（相对于预览区域）
                switch (align) {
                    case 'left':
                        x = previewX + 10;
                        break;
                    case 'center':
                        x = previewX + minWidth / 2;
                        break;
                    case 'right':
                        x = previewX + minWidth - 10;
                        break;
                }
                
                // Y坐标使用预览区域中心
                y = previewY + minHeight / 2 + size / 3;
                
                // 绘制预览矩形区域
                this.ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
                this.ctx.lineWidth = 2;
                this.ctx.setLineDash([5, 5]);
                this.ctx.strokeRect(previewX, previewY, minWidth, minHeight);
                this.ctx.setLineDash([]);
                
                // 绘制描边预览文本
                if (strokeWidth > 0) {
                    this.ctx.strokeStyle = strokeColor;
                    this.ctx.lineWidth = strokeWidth;
                    this.ctx.strokeText(text, x, y);
                }
                
                // 绘制填充预览文本
                this.ctx.fillStyle = color;
                this.ctx.fillText(text, x, y);
                
                this.ctx.restore();
            }
            
            createSubtitle(start, end) {
                const text = document.getElementById('subtitleText').value;
                const color = document.getElementById('subtitleColor').value;
                const strokeColor = document.getElementById('subtitleStrokeColor').value;
                const strokeWidth = parseInt(document.getElementById('subtitleStrokeWidth').value);
                const size = parseInt(document.getElementById('subtitleSize').value);
                const align = document.getElementById('subtitleAlign').value;
                const opacity = parseInt(document.getElementById('subtitleOpacity').value);
                
                // 确保最小尺寸
                const minWidth = Math.max(100, Math.abs(end.x - start.x));
                const minHeight = Math.max(size + 20, Math.abs(end.y - start.y));
                
                // 计算字幕区域位置（基于鼠标拖拽范围）
                const subtitleX = Math.min(start.x, end.x);
                const subtitleY = Math.min(start.y, end.y);
                
                const subtitle = {
                    id: Date.now(),
                    text: text,
                    x: subtitleX,
                    y: subtitleY,
                    width: minWidth,
                    height: minHeight,
                    color: color,
                    strokeColor: strokeColor,
                    strokeWidth: strokeWidth,
                    size: size,
                    align: align,
                    opacity: opacity
                };
                
                this.subtitles.push(subtitle);
                this.updateSubtitleCount();
                this.drawSubtitles();
            }
            
            createSubtitleAtPosition(position) {
                const text = document.getElementById('subtitleText').value;
                const color = document.getElementById('subtitleColor').value;
                const strokeColor = document.getElementById('subtitleStrokeColor').value;
                const strokeWidth = parseInt(document.getElementById('subtitleStrokeWidth').value);
                const size = parseInt(document.getElementById('subtitleSize').value);
                const align = document.getElementById('subtitleAlign').value;
                const opacity = parseInt(document.getElementById('subtitleOpacity').value);
                
                // 创建默认大小的字幕区域
                const defaultWidth = 200;
                const defaultHeight = size + 40;
                
                const subtitle = {
                    id: Date.now(),
                    text: text,
                    x: position.x - defaultWidth / 2, // 以点击位置为中心
                    y: position.y - defaultHeight / 2,
                    width: defaultWidth,
                    height: defaultHeight,
                    color: color,
                    strokeColor: strokeColor,
                    strokeWidth: strokeWidth,
                    size: size,
                    align: align,
                    opacity: opacity
                };
                
                // 确保字幕区域在画布范围内
                subtitle.x = Math.max(0, Math.min(this.canvas.width - subtitle.width, subtitle.x));
                subtitle.y = Math.max(0, Math.min(this.canvas.height - subtitle.height, subtitle.y));
                
                this.subtitles.push(subtitle);
                this.updateSubtitleCount();
                this.drawSubtitles();
            }
            
            clearAllSubtitles() {
                this.subtitles = [];
                this.subtitleFile = null; // 清除字幕文件引用
                document.getElementById('subtitleFileStatus').textContent = '未上传';
                this.updateSubtitleCount();
                this.drawSubtitles();
                this.updateSubtitleDataOutput();
            }
            
            updateSubtitleCount() {
                document.getElementById('positionCount').textContent = this.subtitles.length;
            }
            
            updateCanvasSize() {
                document.getElementById('canvasSize').textContent = 
                    `${this.canvas.width} x ${this.canvas.height}`;
            }
            
            getSubtitleData() {
                // 获取当前的字幕样式设置
                const currentText = document.getElementById('subtitleText').value;
                const currentColor = document.getElementById('subtitleColor').value;
                const currentStrokeColor = document.getElementById('subtitleStrokeColor').value;
                const currentStrokeWidth = parseInt(document.getElementById('subtitleStrokeWidth').value);
                const currentSize = parseInt(document.getElementById('subtitleSize').value);
                const currentAlign = document.getElementById('subtitleAlign').value;
                const currentOpacity = parseInt(document.getElementById('subtitleOpacity').value);
                
                // 获取画布上的字幕位置设置
                const subtitlePositions = this.subtitles.map(subtitle => ({
                    id: subtitle.id,
                    x: Math.round(subtitle.x),
                    y: Math.round(subtitle.y),
                    width: Math.round(subtitle.width),
                    height: Math.round(subtitle.height)
                }));
                
                const data = {
                    canvas: {
                        width: this.canvas.width,
                        height: this.canvas.height
                    },
                    subtitle_positions: subtitlePositions, // 画布上的位置设置
                    subtitle_style: { // 统一的字幕样式设置
                        text: currentText,
                        color: currentColor,
                        strokeColor: currentStrokeColor,
                        strokeWidth: currentStrokeWidth,
                        size: currentSize,
                        align: currentAlign,
                        opacity: currentOpacity
                    },
                    timestamp: new Date().toISOString()
                };
                
                this.updateSubtitleDataOutput(data);
                return data;
            }
            
            updateSubtitleDataOutput(data = null) {
                const output = document.getElementById('subtitleDataOutput');
                if (data) {
                    output.textContent = JSON.stringify(data, null, 2);
                } else {
                    output.textContent = '暂无字幕数据';
                }
            }
            
            async applySubtitleToVideo() {
                if (!this.videoElement.src) {
                    alert('请先选择视频文件！');
                    return;
                }
                
                console.log('检查字幕文件:', this.subtitleFile);
                if (!this.subtitleFile) {
                    alert('请先上传字幕文件！');
                    return;
                }
                
                try {
                    // 先获取字幕数据
                    const subtitleData = this.getSubtitleData();
                    
                    // 创建FormData
                    const formData = new FormData();
                    
                    // 从视频URL创建文件对象
                    const response = await fetch(this.videoElement.src);
                    const blob = await response.blob();
                    const file = new File([blob], 'video.mp4', { type: 'video/mp4' });
                    
                    formData.append('video', file);
                    formData.append('subtitle', this.subtitleFile);
                    formData.append('subtitle_data', JSON.stringify(subtitleData));
                    
                    console.log('发送数据:', {
                        video: file.name,
                        subtitle: this.subtitleFile.name,
                        subtitleData: subtitleData
                    });
                    
                    // 显示处理状态
                    document.getElementById('drawStatus').textContent = '正在处理视频...';
                    
                    // 发送请求到后端
                    const apiResponse = await fetch('/subtitle/apply', {
                        method: 'POST',
                        body: formData
                    });
                    
                    if (apiResponse.ok) {
                        // 下载处理后的视频
                        const resultBlob = await apiResponse.blob();
                        const url = window.URL.createObjectURL(resultBlob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = 'subtitle_video.mp4';
                        document.body.appendChild(a);
                        a.click();
                        document.body.removeChild(a);
                        window.URL.revokeObjectURL(url);
                        
                        document.getElementById('drawStatus').textContent = '处理完成！';
                        alert('字幕视频生成成功！');
                    } else {
                        const errorData = await apiResponse.json();
                        throw new Error(errorData.error || '处理失败');
                    }
                    
                } catch (error) {
                    console.error('处理失败:', error);
                    document.getElementById('drawStatus').textContent = '处理失败';
                    alert('处理失败: ' + error.message);
                }
            }

            handleSubtitleFileUpload(file) {
                if (!file) return;
                
                // 保存字幕文件引用，不解析内容
                this.subtitleFile = file;
                document.getElementById('subtitleFileStatus').textContent = file.name;
                console.log('字幕文件已保存:', file.name, file.size);
                alert(`字幕文件 "${file.name}" 已选择，将在生成视频时使用。`);
            }
        }
        
        // 初始化工具
        document.addEventListener('DOMContentLoaded', () => {
            new SubtitleTool();
        });
    </script>
</body>
</html> 